package net.homeip.jcperera.nu.core.persistence;

import java.io.Serializable;
import java.math.BigDecimal;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Query;

import net.homeip.jcperera.nu.core.CoreBase;
import net.homeip.jcperera.nu.core.boot.Boot;
import sun.rmi.runtime.Log;

/**
 * <p>
 * GlobalSequence is a function library class, whose only purpose is to provide a global database based sequence to the
 * framework for versioning purposes. Functions in this library are higher level than some other function libraries in
 * the framework and therefore this conforms to the {@link CoreBase} interface in order to use a {@link Log} inside any
 * function when needed.
 * </p>
 * <p>
 * <b>Note:</b> At this time the only database platform supported is ORACLE. This will change in the future.
 * </p>
 * 
 * @name GlobalSequence functions
 * @author julio.c.perera@gmail.com
 * @application nu
 * @since 0.1.0.0
 */
public class GlobalSequence extends CoreBase implements Serializable
{
    // Required to implement Serializable interface
    private static final long  serialVersionUID = 3848757382640558205L;

    // CoreBase properties, for easy use from other components, as well as logging
    public static final int    runtimeLevel     = 0;
    public static final String moduleName       = "core";
    public static final String componentName    = "nu_core_persistence_global_sequence";

    /**
     * <p>
     * Gets the next number from the database sequence and returns it, the sequence should be created automatically at
     * startup when needed by JPA.
     * </p>
     * <p>
     * <b>Note:</b> At this time the only database platform supported is ORACLE. This will change in the future.
     * </p>
     * 
     * @return The next global sequence number
     */
    public static long getNextValue(String sequenceName)
    {
        Persistence persistence = Boot.getSystem().getPersistence();

        Long result = 0L;
        EntityManagerFactory emf = persistence.getEntityManagerFactory();
        EntityManager em = (EntityManager) emf.createEntityManager();

        String platform = EclipseLinkInfoAdapter.determineTargetDatabase();
        if (platform.equalsIgnoreCase("ORACLE"))
        {
            Query query = em.createNativeQuery("SELECT " + sequenceName + ".NEXTVAL FROM DUAL");
            result = ((BigDecimal) query.getSingleResult()).longValue();
        }
        // TODO: Make specific sentences for the rest of the supported DBs

        em.close();

        return result;
    }
}
